package com.xbongbong.pro.dataset.node;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.bi.pojo.DataSetNodeInputPojo;
import com.xbongbong.paas.constant.XbbConstant;
import com.xbongbong.paas.enums.bi.DataSetNodeTypeEnum;
import com.xbongbong.paas.enums.bi.XbbTableRefEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.pro.bi.commons.pojo.ParamPojo;
import com.xbongbong.pro.bi.commons.sql.SqlBuilderHandler;
import com.xbongbong.pro.bi.commons.sql.SqlInfo;
import com.xbongbong.pro.dataset.helper.JsqlParseHelper;
import com.xbongbong.pro.statistic.pojo.ChartFieldAttrPojo;
import com.xbongbong.pro.statistic.pojo.dto.SqlParseDTO;
import com.xbongbong.pro.statistics.help.CommonHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * @author gzt
 * @version 1.0
 * @Description -
 * @datetime - 2022/5/23-10:20
 * @since v1.0
 */
@Component
public class InputNodeStrategy implements NodeStrategy {
    @Resource
    JsqlParseHelper jsqlParseHelper;
    @Override
    public void parseNodeToSql(SqlParseDTO sqlParseDTO) throws XbbException {
        String nodeId = sqlParseDTO.getNodeId();
        JSONObject jsonObject = sqlParseDTO.getJsonObject();
        DataSetNodeInputPojo inputNode = JSONObject.parseObject(JSON.toJSONString(jsonObject, SerializerFeature.DisableCircularReferenceDetect), DataSetNodeInputPojo.class);
        Set<String> fieldCheckSet = inputNode.getFieldChecked().stream().map(field->{
            if (field.contains(XbbConstant.POINT)){
               field = field.split("\\.")[0];
            }
            return field;
        }).collect(Collectors.toCollection(TreeSet::new));
        //fieldCheckSet.add(FieldTypeEnum.ID.getAlias());
        List<ChartFieldAttrPojo> hideField = inputNode.getHideField();
        if(CollectionsUtil.isNotEmpty(hideField)){
            fieldCheckSet.addAll(hideField.stream().map(FieldAttrEntity::getAttr).collect(Collectors.toSet()));
        }
        Long formId = inputNode.getFormId();
        Map<Long, String> formIdTableMap = sqlParseDTO.getFormIdTableMap();
        String tableName = formIdTableMap.get(formId);
        Map<String, String> nodeTableNameMap = NODE_TABLE_NAME_THREAD_LOCAL.get();
        nodeTableNameMap.put(nodeId,tableName);
        Integer businessType = inputNode.getBusinessType();
        Integer saasMark = inputNode.getSaasMark();
        ParamPojo paramPojo = new ParamPojo();
        paramPojo.setFormId(formId);
        paramPojo.setBusinessType(businessType);
        paramPojo.setSaasMark(saasMark);
        paramPojo.setCorpid(sqlParseDTO.getCorpid());
        SqlBuilderHandler sqlBuilder = SqlBuilderHandler.start();
        List<ChartFieldAttrPojo> field = inputNode.getField();
        //兼容预览和存储生成sql的区别,预览的时候有field
        /*if(CollectionsUtil.isNotEmpty(field)){
            field =  field.stream().filter(chartFieldAttrPojo -> !Objects.equals(chartFieldAttrPojo.getAttr(),FieldTypeEnum.DATAID.getAlias()) && !Objects.equals(chartFieldAttrPojo.getAttr(),FieldTypeEnum.ID.getAlias())).collect(Collectors.toList());
        }*/
        field = null;
        SqlBuilderHandler teamJoinSqlH = jsqlParseHelper.generatItems(tableName, sqlBuilder, fieldCheckSet, formIdTableMap, sqlParseDTO, paramPojo, field,null);
        //单个input 节点预览需要append 团队表
        if (Objects.nonNull(teamJoinSqlH) && sqlParseDTO.isInputPreView()){
            sqlBuilder.append(XbbConstant.R_P + XbbConstant.AS + tableName,false);
            if (Objects.nonNull(sqlBuilder.end().getSql())) {
                String teamName = XbbTableRefEnum.getTeamNameByParent(businessType);
                if (StringUtils.isNotEmpty(teamName) && sqlBuilder.end().getSql().contains(teamName)) {
                    String teamSql = teamJoinSqlH.end().getSql();
                    sqlBuilder.append(teamSql);
                }
            }
        }
        SqlInfo sqlInfo = sqlBuilder.end();
        String sql = sqlInfo.getSql();
        Map<String, String> sqlNodes = SQL_NODES_THREAD_LOCAL.get();
        sqlNodes.putIfAbsent(nodeId,sql);
        NODE_TYPE_THREAD_LOCAL.get().put(nodeId,getNodeType());
        Map<String, String> nodeFormIdMap = NODE_FORM_ID_THREAD_LOCAL.get();
        nodeFormIdMap.putIfAbsent(nodeId,formId+XbbConstant.SEPARATOR+ CommonHelper.getTeamNameByBusinessType(businessType));
    }

    @Override
    public String getNodeType() {
        return DataSetNodeTypeEnum.INPUT.getAlias();
    }

    @Override
    public String getParseSql(String nodeId) {
        return SQL_NODES_THREAD_LOCAL.get().get(nodeId);
    }
}
